package netty.udp;

import io.netty.bootstrap.Bootstrap;
import io.netty.buffer.PooledByteBufAllocator;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioDatagramChannel;
import netty.common.serializer.UdpDecoder;
import netty.common.serializer.UdpEncoder;
import test.PerformanceAnalyze;

import java.util.Random;

/**
 * <B>说	明<B/>:LogPush UDP client
 */
public class UdpClient {

    static PerformanceAnalyze performanceAnalyze = new PerformanceAnalyze();

    private final Random random = new Random();
    private final int port = random.nextInt(60000);

    private ChannelFuture channelFuture;

    public void start() throws Exception {
        try {
            NioEventLoopGroup workerGroup = new NioEventLoopGroup();

            Bootstrap bootstrap = new Bootstrap();
            bootstrap.group(workerGroup)
                    .channel(NioDatagramChannel.class)
                    .option(ChannelOption.SO_BROADCAST, false)
                    .option(ChannelOption.SO_SNDBUF, 300 * 1024 * 1024)
                    .option(ChannelOption.SO_RCVBUF, 300 * 1024 * 1024)
                    .option(ChannelOption.ALLOCATOR, PooledByteBufAllocator.DEFAULT)
                    .handler(new ChannelInitializer<NioDatagramChannel>() {
                        @Override
                        protected void initChannel(NioDatagramChannel ch) throws Exception {
                            ch.pipeline().addLast(new UdpEncoder());
                            ch.pipeline().addLast(new UdpDecoder());
                            ch.pipeline().addLast(new ClientHandler());
                        }
                    });
            channelFuture = bootstrap.bind(port).sync();
//            channel.closeFuture().await(1000);
        } finally {
//        	workerGroup.shutdownGracefully();
        }

    }

    public void sendMsg(com.zetas.option.push.message.sdk.PushSDKMessage.Message4Backend msg, boolean needFlush) {
        long now = System.nanoTime();
        if (needFlush) {
            channelFuture.channel().writeAndFlush(msg).addListener(future -> {
                performanceAnalyze.delay(System.nanoTime() - now);
            });
        } else {
            channelFuture.channel().write(msg).addListener(future -> {
                performanceAnalyze.delay(System.nanoTime() - now);
            });
        }

        performanceAnalyze.meter();
    }

}
